#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ModBus_Thread
# start a thread for polling a set of registers, display result on console
# exit with ctrl+c

#   yes  self.c.read_input_registers()
#   yes  self.c.read_coils()
#   yes  self.c.read_holding_registers()
#   yes  self.c.write_multiple_coils()
#   yes  self.c.write_multiple_registers()

#   self.c.read_discrete_inputs()
#   self.c.write_single_coil()
#   self.c.write_single_register()

import time
from random import randint
from threading import Lock

from PyQt5.QtCore import QObject
from pyModbusTCP.client import ModbusClient
import lib.applets as sApp
import Globalist as gl


# ModBus polling thread for PLC communication
class QPollThread(QObject):
    def __init__(self, threadNum=None):
        super().__init__()
        # init a thread lock
        self.regs_lock = Lock()
        self.c = None
        aa = threadNum.split("-")
        self.strIp = aa[1]
        self.eNum = int(aa[2])
        self.SERVER_PORT = 502
        self.bWriting = False
        ''''''

    def polling_thread(self):
        # polling loop
        if not self.strIp and not self.SERVER_PORT:
            return
        else:
            try:
                self.c = ModbusClient(host=self.strIp, port=self.SERVER_PORT, timeout=1)
            except BaseException as e:
                print(e)
                return
        while True:
            if not self.c.is_open():
                self.c.open()
            if True:
                # do ModBus reading on socket
                regBit_list = []
                reg_list = []
                aa = gl.global_var["Plc_read_area"]["data_rdArea1"]["dArea"][str(self.eNum)]
                if aa[0] == "bit":
                    regBit_list = self.c.read_coils(aa[1], len(aa[2]))  # 读信捷PLC/其他的状态
                elif aa[0] == "word":
                    reg_list = self.c.read_holding_registers(aa[1], len(aa[2]))  # 砂光机
                ''''''
                if regBit_list or reg_list:
                    gl.global_var["deviceIpDict"][self.eNum][1] = 1
                else:
                    gl.global_var["deviceIpDict"][self.eNum][1] = 0
                ''''''
                if regBit_list:
                    gl.global_var["Plc_read_area"]["data_rdArea1"]["dArea"][str(self.eNum)][2] = regBit_list
                if reg_list:
                    gl.global_var["Plc_read_area"]["data_rdArea1"]["dArea"][str(self.eNum)][2] = reg_list
                ''''''
                regBit_list2 = []
                reg_list2 = []
                bb = gl.global_var["Plc_read_area"]["data_rdArea2"]["dArea"]
                if str(self.eNum) in bb.keys():
                    aa = gl.global_var["Plc_read_area"]["data_rdArea2"]["dArea"][str(self.eNum)]
                    if aa[0] == "bit":
                        regBit_list2 = self.c.read_coils(aa[1], len(aa[2]))  # 读信捷PLC/其他的状态
                    elif aa[0] == "word":
                        reg_list2 = self.c.read_holding_registers(aa[1], len(aa[2]))
                    if regBit_list2:
                        gl.global_var["Plc_read_area"]["data_rdArea2"]["dArea"][str(self.eNum)][2] = regBit_list2
                    if reg_list2:
                        gl.global_var["Plc_read_area"]["data_rdArea2"]["dArea"][str(self.eNum)][2] = reg_list2
                ''''''
                regBit_list3 = []
                reg_list3 = []
                bb = gl.global_var["Plc_read_area"]["data_rdArea3"]["dArea"]
                if str(self.eNum) in bb.keys():
                    aa = gl.global_var["Plc_read_area"]["data_rdArea3"]["dArea"][str(self.eNum)]
                    if aa[0] == "bit":
                        regBit_list3 = self.c.read_coils(aa[1], len(aa[2]))  # 读信捷PLC/其他的状态
                    elif aa[0] == "word":
                        reg_list3 = self.c.read_holding_registers(aa[1], len(aa[2]))
                    if regBit_list3:
                        gl.global_var["Plc_read_area"]["data_rdArea3"]["dArea"][str(self.eNum)][2] = regBit_list3
                    if reg_list3:
                        gl.global_var["Plc_read_area"]["data_rdArea3"]["dArea"][str(self.eNum)][2] = reg_list3

                regBit_list4 = []
                reg_list4 = []
                bb = gl.global_var["Plc_read_area"]["data_rdArea4"]["dArea"]
                if str(self.eNum) in bb.keys():
                    aa = gl.global_var["Plc_read_area"]["data_rdArea4"]["dArea"][str(self.eNum)]
                    if aa[0] == "bit":
                        regBit_list4 = self.c.read_coils(aa[1], len(aa[2]))  # 读信捷PLC/其他的状态
                    elif aa[0] == "word":
                        # 仅仅测试
                        # reg_list4 = []
                        # for i in range(len(aa[2])):
                        #     reg_list4.append(randint(0, 30))
                        reg_list4 = self.c.read_holding_registers(aa[1], len(aa[2]))
                    if regBit_list4:
                        gl.global_var["Plc_read_area"]["data_rdArea4"]["dArea"][str(self.eNum)][2] = regBit_list4
                    if reg_list4:
                        aa = gl.global_var["Plc_read_area"]["data_rdArea4"]["dArea"][str(self.eNum)]
                        bb = []
                        for i in range(len(reg_list4)):
                            if aa[3] == 0:
                                bb.append(float(sApp.u2s(reg_list4[i])))
                            elif aa[3] == 1:
                                bb.append(float(sApp.u2s(reg_list4[i])) / 10.0)
                            elif aa[3] == 2:
                                bb.append(float(sApp.u2s(reg_list4[i])) / 100.0)
                        gl.global_var["Plc_read_area"]["data_rdArea4"]["dArea"][str(self.eNum)][2] = bb

                '''write Plc'''
                '''以下是循环写入数据'''
                # self.c.write_multiple_registers(0, rwList)  # 写区域
                # 1 连线信号
                aa = gl.global_var["Plc_write"]["link_signal"]
                for key, value in aa.items():
                    if key == str(self.eNum):
                        self.c.write_multiple_coils(value[0], value[1])
                # 2 远程联机
                aa = gl.global_var["Plc_write"]["bOnlineDict"]
                for key, value in aa.items():
                    if key == str(self.eNum):
                        self.c.write_multiple_coils(value[0], value[1])
                # 3
                bResetList = [gl.global_var["operateVar"]["bReset"]]
                self.c.write_multiple_coils(121, bResetList)
                # 4
                bStartStopList = [gl.global_var["operateVar"]["bOneStart"], gl.global_var["operateVar"]["bOneStop"]]
                self.c.write_multiple_coils(700, bStartStopList)
                # 5
                if self.eNum not in [0, 9, 14, 17, 16]:
                    pass
                    # aa = gl.global_var["Plc_write"]["SpeedSet"][str(self.eNum)]
                    # self.c.write_multiple_registers(aa[0], aa[1])
                # 6 height
                if self.eNum not in [9, 14, 17]:
                    if gl.global_var["send_plc_pool"][str(self.eNum)]:
                        aa = gl.global_var["send_plc_pool"][str(self.eNum)][0]
                        self.c.write_multiple_coils(aa[0], aa[1])
                        gl.global_var["send_plc_pool"][str(self.eNum)].pop(0)
                # 7，数据对接
                aa1 = gl.global_var["monitorVar"]["cloudBitData"]
                aa2 = gl.global_var["monitorVar"]["cloudWordData"]
                if self.eNum == 0:
                    self.c.write_multiple_coils(0, aa1)
                    self.c.write_multiple_registers(6000, aa2)

            '''处理信号'''
            pass
            # print(self.bWriteList)
            # 0.1s before next polling
            time.sleep(0.1)

    def stopPoll(self):
        pass

    def startPoll(self):
        pass

    def startThread(self):
        pass

    '''XinJe Plc'''

    def readXinJePlc(self):
        regBit_list = self.c.read_coils(600, 10)  # 读信捷PLC状态
        # regBit_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        if regBit_list:
            gl.global_var["deviceIpDict"][self.eNum][1] = 1
            ''''''
            gl.global_var["Plc_Interface"]["M600"][str(self.eNum)] = regBit_list
        else:
            gl.global_var["deviceIpDict"][self.eNum][1] = 0

        if self.eNum == 1:
            reg_list0 = self.c.read_holding_registers(2006, 1)  # 输送带速度
            if reg_list0:
                gl.global_var["monitorVar"]["CurVelocity"] = float(reg_list0[0]) / 10.0

        if self.eNum in [1, 3, 4, 7, 10, 12, 15]:
            reg_list1 = self.c.read_holding_registers(2010, 3)  # 高度
            if reg_list1:
                gl.global_var["Plc_Interface"]["D2010"][str(self.eNum)] = reg_list1
            reg_list2 = self.c.read_holding_registers(3000, 3)  # 高度
            if reg_list2:
                gl.global_var["Plc_Interface"]["D3000"][str(self.eNum)] = reg_list2

        if self.eNum == 16:
            reg_list = self.c.read_holding_registers(41090, 4)  # 平方数
            if reg_list:
                try:
                    aa1 = sApp.hex_2_f(sApp.To_hex_str(reg_list[0]), sApp.To_hex_str(reg_list[1]))
                    aa2 = sApp.hex_2_f(sApp.To_hex_str(reg_list[2]), sApp.To_hex_str(reg_list[3]))
                    gl.global_var["monitorVar"]["TotalAmount"] = round(aa1, 1)
                    gl.global_var["monitorVar"]["CurSpeed"] = round(aa2, 1)  # 生产速度
                except BaseException as e:
                    print(e)

    '''砂光机'''

    def readSanderPlc(self):
        reg_list = self.c.read_holding_registers(0, 14)  # 砂光机1
        if self.eNum == 9:
            if reg_list:
                gl.global_var["Plc_Interface"]["4X0"]["9"] = reg_list
                gl.global_var["deviceIpDict"][self.eNum][1] = 1
            else:
                gl.global_var["deviceIpDict"][self.eNum][1] = 0
        elif self.eNum == 14:
            if reg_list:
                gl.global_var["Plc_Interface"]["4X0"]["14"] = reg_list
                gl.global_var["deviceIpDict"][self.eNum][1] = 1
            else:
                gl.global_var["deviceIpDict"][self.eNum][1] = 0


if __name__ == '__main__':
    tpj = QPollThread()
    tpj.startThread()
